package org.jmetrix.group;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * @author Konstantin Kuzmin
 * @version $Revision$
 * @since 01.10.11
 */
//TODO abstract from AspectJ
//TODO add debug logging
public abstract class GroupAspect {
    protected abstract String getGroup(ProceedingJoinPoint pjp);


    protected Object group(ProceedingJoinPoint pjp) throws Throwable {
        GroupSequence groupSequence = GroupSequence.getThreadLocal().get();
        groupSequence.add(getGroup(pjp));
        try {
            return proceed(pjp);
        } finally {
            groupSequence.removeLast();
        }
    }

    protected boolean isInGroup(final String group) {
        String[] groups = GroupSequence.getThreadLocal().get().getGroups();
        for (int i = groups.length - 1; i >= 0; i--) {
            if (group.equals(groups[i])) {
                return true;
            }
        }
        return false;
    }

    protected Object proceed(ProceedingJoinPoint pjp) throws Throwable {
        return pjp.proceed();
    }

    public Object measure(final ProceedingJoinPoint pjp) throws Throwable {
        return group(pjp);
    }

    //TODO test
    public Object measureOnce(final ProceedingJoinPoint pjp) throws Throwable {
        if (!isInGroup(getGroup(pjp))) {
            return group(pjp);
        } else {
            return pjp.proceed();
        }
    }
}